package com.fdsc.erp.weixin.Message;

import com.fdsc.erp.weixin.Message.resp.*;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDomDriver;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:消息处理工具类
 * @Author:lishanhui
 * @Date:Create in 17:07  2018-06-05
 **/
public class MessageUtil {
    //请求消息类型:文本
    public static final String REQ_MESSAGE_TYPE_TEXT = "text";
    //请求消息类型:图片
    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
    //请求消息类型:语音
    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
    //请求消息类型:视频
    public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
    //请求消息类型:地理位置
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
    //请求消息类型:链接
    public static final String REQ_MESSAGE_TYPE_LINK = "link";
    //请求消息类型:事件推送
    public static final String REQ_MESSAGE_TYPE_EVENT = "event";

    //事件类型：subscribe（订阅）
    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
    //事件类型：unsubscribe（取消订阅）
    public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
    //事件类型：scan (关注用户扫描带参数二维码)
    public static final String EVENT_TYPE_SCAN = "SCAN";
    //事件类型：location（上报地理位置）
    public static final String EVENT_TYPE_LOCATION = "LOCATION";
    //事件类型：click（自定义菜单）
    public static final String EVENT_TYPE_CLICK = "CLICK";

    //响应消息类型:文本
    public static final String REQP_MESSAGE_TYPE_TEXT = "text";
    //响应消息类型:图片
    public static final String REQP_MESSAGE_TYPE_IMAGE = "image";
    //响应消息类型:语音
    public static final String REQP_MESSAGE_TYPE_VOICE = "voice";
    //响应消息类型:视频
    public static final String REQP_MESSAGE_TYPE_VIDEO = "video";
    //响应消息类型:音乐
    public static final String REQP_MESSAGE_TYPE_MUSIC = "music";
    //响应消息类型:图文
    public static final String REQP_MESSAGE_TYPE_NEWS = "news";

    /**
     *@Date:Create in 9:05 2018-06-06
     *@Description:解析微信发来的请求 （XML）
     *@params: * @param request
     *@return:
     **/
    @SuppressWarnings("unchecked")
    public static Map<String,String> parseXml(HttpServletRequest request) throws Exception {
        //将解析结果存储在HashMap中
        Map<String,String> map = new HashMap<String,String>();
        //从request 中取得输入流
        InputStream in = request.getInputStream();
        //读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(in);
        //得到XML根元素
        Element root = document.getRootElement();
        //得到根元素的所有子字节点
        List<Element> elementList = root.elements();
        //遍历所有子节点
        for (Element e : elementList){
            map.put(e.getName(),e.getText());
        }
        //释放资源
        in.close();
        in = null;
        return map;
    }
    /**
     *@Date:Create in 9:22 2018-06-06
     *@Description:扩展xstream使其支持CDATA
     *@params: * @param null
     *@return:
     **/
    private static XStream xstream = new XStream(new XppDomDriver(){
        @Override
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out){
                //对所有XML节点的转换都增加CDATA标记
                boolean cdata = true;

                @SuppressWarnings("unchecked")
                public void startNode(String name,Class clazz){
                    super.startNode(name, clazz);
                }

                protected void writeText(QuickWriter writer,String text){
                    if (cdata){
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    }else {
                        writer.write(text);
                    }
                }
            };
        }
    });

    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:文本消息对象转换XML
     *@params: * @param textMessage 文本消息对象
     *@return:xml
     **/
    public static String messageToXml(TextMessage textMessage){
        xstream.alias("xml",textMessage.getClass());
        return xstream.toXML(textMessage);
    }


    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:图片消息对象转换XML
     *@params: * @param ImageMessage 图片消息对象
     *@return:xml
     **/
    public static String messageToXml(ImageMessage imageMessage){
        xstream.alias("xml",imageMessage.getClass());
        return xstream.toXML(imageMessage);
    }

    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:语音消息对象转换XML
     *@params: * @param VoiceMessage 语音消息对象
     *@return:xml
     **/
    public static String messageToXml(VoiceMessage voiceMessage){
        xstream.alias("xml",voiceMessage.getClass());
        return xstream.toXML(voiceMessage);
    }

    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:视频消息对象转换XML
     *@params: * @param VideoMessage 视频消息对象
     *@return:xml
     **/
    public static String messageToXml(VideoMessage videoMessage){
        xstream.alias("xml",videoMessage.getClass());
        return xstream.toXML(videoMessage);
    }

    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:音乐消息对象转换XML
     *@params: * @param MusicMessage 音乐消息对象
     *@return:xml
     **/
    public static String messageToXml(MusicMessage musicMessage){
        xstream.alias("xml",musicMessage.getClass());
        return xstream.toXML(musicMessage);
    }

    /**
     *@Date:Create in 9:25 2018-06-06
     *@Description:图文消息对象转换XML
     *@params: * @param NewsMessage 图文消息对象
     *@return:xml
     **/
    public static String messageToXml(NewsMessage newsMessage){
        xstream.alias("xml",newsMessage.getClass());
        xstream.alias("item",new Article().getClass());
        return xstream.toXML(newsMessage);
    }

}
